package com.leyou.trade.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leyou.auth.utils.UserContext;
import com.leyou.common.exception.LyException;
import com.leyou.item.client.ItemClient;
import com.leyou.item.dto.SkuDTO;
import com.leyou.trade.dto.OrderDTO;
import com.leyou.trade.dto.OrderFormDTO;
import com.leyou.trade.entity.Order;
import com.leyou.trade.entity.OrderDetail;
import com.leyou.trade.entity.OrderLogistics;
import com.leyou.trade.entity.OrderStatus;
import com.leyou.trade.mapper.OrderMapper;
import com.leyou.trade.service.OrderDetailService;
import com.leyou.trade.service.OrderLogisticsService;
import com.leyou.trade.service.OrderService;
import com.leyou.user.client.UserClient;
import com.leyou.user.dto.AddressDTO;
import feign.FeignException;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private OrderDetailService orderDetailService;

    @Autowired
    private OrderLogisticsService orderLogisticsService;

    @Autowired
    private UserClient userClient;

    @Autowired
    private ItemClient itemClient;

    @Override
    @Transactional
    public Long createOrder(@Valid OrderFormDTO orderFormDTO) {

        // 1. 创建一个order对象
        Order order = new Order();

        // 2.获取到用户id
        Long userId = UserContext.getUser().getId();
        order.setUserId(userId);

        // 3.获取提交的订单中的商品信息
        Map<Long, Integer> carts = orderFormDTO.getCarts();

        // 4.获取map集合中的商品所有的sku id
        List<Long> skuIds = new ArrayList<>(carts.keySet());

        // 5.根据sku id的集合信息查询sku
        List<SkuDTO> skuDTOS = this.itemClient.querySkuByIds(skuIds);

        // 6.计算商品的金额
        long total = 0;
        for (SkuDTO skuDTO : skuDTOS) {

            // 根据sku的id获取到订单提交的本商品的数量
            Integer num = carts.get(skuDTO.getId());

            total += skuDTO.getPrice() * num ;

        }

        // 填写金额费用
        order.setTotalFee(total);

        order.setPaymentType(orderFormDTO.getPaymentType());

        order.setPostFee(0L); // 去除邮费的计算

        order.setActualFee(total + order.getPostFee() /*- 优惠金额*/);

        // 订单状态初始化
        order.setStatus(OrderStatus.INIT);

        // 写order到数据库
        boolean flag = this.save(order);

        if (!flag) {

            throw new LyException(HttpStatus.INTERNAL_SERVER_ERROR.value(),"创建订单失败！");

        }

        // 编写订单的详细信息
        List<OrderDetail> orderDetailList = new ArrayList<>();

        // 遍历sku集合，转为orderDetail
        for (SkuDTO skuDTO : skuDTOS) {

            // 商品数量
            Integer num = carts.get(skuDTO.getId());

            // 组装orderDetail
            OrderDetail orderDetail = new OrderDetail();

            orderDetail.setOrderId(order.getOrderId());

            orderDetail.setSkuId(skuDTO.getId());

            orderDetail.setNum(num);

            orderDetail.setTitle(skuDTO.getTitle());

            orderDetail.setPrice(skuDTO.getPrice());

            orderDetail.setSpec(skuDTO.getSpecialSpec());

            orderDetail.setImage(StringUtils.substringBefore(skuDTO.getImages(),","));

            // 装入detail集合
            orderDetailList.add(orderDetail);

        }

        // 批量新增
        flag = orderDetailService.saveBatch(orderDetailList);

        if (!flag) {

            throw new LyException(HttpStatus.INTERNAL_SERVER_ERROR.value(),"创建订单失败！");

        }

        // 编写订单的物流信息 orderLogistics

        // 查询收货地址
        AddressDTO address = this.userClient.queryAddressById(orderFormDTO.getAddressId());

        // 填写物流信息
        OrderLogistics orderLogistics = address.toEntity(OrderLogistics.class);

        orderLogistics.setOrderId(order.getOrderId());

        // 写入数据库
        flag = orderLogisticsService.save(orderLogistics);

        if (!flag) {

            throw new LyException(HttpStatus.INTERNAL_SERVER_ERROR.value(),"创建订单失败！");

        }

        // 减库存
        try {

            this.itemClient.deductStock(carts);

        } catch (FeignException e) {

            throw new LyException(e.status(),e.contentUTF8());

        }

        return order.getOrderId();

    }

    @Override
    public OrderDTO queryOrderById(Long orderId) {

        return new OrderDTO(this.getById(orderId));

    }
}
